#define _GNU_SOURCE
#include "app_serial.h"
#include <unistd.h>
#include <stdio.h>
#include "log/log.h"
/**
 * 设置波特率
 */
int app_serial_setBraudRate(Device *device, BaudRate baud_rate)
{
    struct termios attr;

    // 获取当前串口属性
    if (tcgetattr(device->fd, &attr) != 0)
    {
        perror("tcgetattr");
        return -1;
    }
    // 设置输入和输出波特率
    cfsetspeed(&attr, baud_rate);

    // 将修改后的属性应用到串口
    if (tcsetattr(device->fd, TCSAFLUSH, &attr) != 0)
    {
        perror("tcsetattr");
        return -1;
    }
    return 0;
}

/**
 * 设置校验位
 */
int app_serial_setParity(Device *device, Parity parity)
{
    struct termios options;
    // 获取当前串口属性
    if (tcgetattr(device->fd, &options) != 0)
    {
        perror("tcgetattr");
        return -1;
    }
    // 清除奇偶校验位标志
    options.c_cflag &= ~(PARENB | PARODD);

    // 设置校验位
    options.c_cflag |= parity;

    // 将修改后的属性应用到串口
    if (tcsetattr(device->fd, TCSAFLUSH, &options) != 0)
    {
        perror("tcsetattr");
        return -1;
    }
    return 0;
}

/**
 * 设置停止位
 */
int app_serial_setStopBits(Device *device, StopBits stop_bits)
{
    struct termios options;
    // 获取当前串口属性
    if (tcgetattr(device->fd, &options) != 0)
    {
        perror("tcgetattr");
        return -1;
    }
    // 清除停止位标志
    options.c_cflag &= ~CSTOPB;

    // 设置停止位
    options.c_cflag |= stop_bits;

    // 将修改后的属性应用到串口,刷新后生效
    if (tcsetattr(device->fd, TCSAFLUSH, &options) != 0)
    {
        perror("tcsetattr");
        return -1;
    }
    return 0;
}

/**
 * 设置是否是阻塞模式
 */
int app_serial_setBlock(Device *device, int is_block)
{
    struct termios options;
    // 获取当前串口属性
    if (tcgetattr(device->fd, &options) != 0)
    {
        perror("tcgetattr");
        return -1;
    }

    if (is_block == 1)
    {
        options.c_cc[VMIN] = 1; // 至少读取一个字符
        options.c_cc[VTIME] = 0; // 没有数据时一直等待
    }
    else
    {
        options.c_cc[VMIN] = 0; // 可以读不到字符
        options.c_cc[VTIME] = 2; // 等待 2*100ms
    }

    // 将修改后的属性应用到串口,刷新后生效
    if (tcsetattr(device->fd, TCSAFLUSH, &options) != 0)
    {
        perror("tcsetattr");
        return -1;
    }
    return 0;
}

/**
 * 设置为原始模式
 */
int app_serial_setRaw(Device *device)
{
    struct termios options;
    // 获取当前串口属性
    if (tcgetattr(device->fd, &options) != 0)
    {
        perror("tcgetattr");
        return -1;
    }

    cfmakeraw(&options);

    // 将修改后的属性应用到串口,刷新后生效
    if (tcsetattr(device->fd, TCSAFLUSH, &options) != 0)
    {
        perror("tcsetattr");
        return -1;
    }
    return 0;
}

/**
 * 初始化
 */
int app_serial_init(Device *device)
{
    app_serial_setBraudRate(device,BR_9600);//蓝牙的初始波特率是9600,测试成功后的波特率是115200
    app_serial_setStopBits(device,SB_1);
    app_serial_setParity(device,Parity_NONE);
    app_serial_setRaw(device);

    int result = tcflush(device->fd, TCIOFLUSH);
    if (result == -1)
    {
        log_error("串口初始化设置失败");
        return -1;
    }
    
    log_debug("串口初始化设置成功");
    return 0;
}